package me.zhengjie.modules.biz.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.biz.domain.*;
import me.zhengjie.modules.biz.repository.*;
import me.zhengjie.modules.biz.service.StorehouseOrderService;
import me.zhengjie.modules.biz.service.dto.*;
import me.zhengjie.modules.biz.service.mapstruct.HazardousChemicalsMapper;
import me.zhengjie.modules.biz.service.mapstruct.StorehouseOrderDetailMapper;
import me.zhengjie.modules.biz.service.mapstruct.StorehouseOrderMapper;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.utils.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.System;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Admin
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2023-03-13
 **/
@Service
@RequiredArgsConstructor
public class StorehouseOrderServiceImpl implements StorehouseOrderService {

    private final StorehouseOrderRepository storehouseOrderRepository;
    private final StorehouseOrderMapper storehouseOrderMapper;
    private final StorehouseOrderDetailRepository storehouseOrderDetailRepository;
    private final StorehouseOrderDetailMapper storehouseOrderDetailMapper;
    private final UserRepository userRepository;
    private final HazardousChemicalsTotalRepository hazardousChemicalsTotalRepository;
    private final HazardousChemicalsRepository hazardousChemicalsRepository;
    private final HazardousChemicalsMapper hazardousChemicalsMapper;
    private final HazardousChemicalsChangeRecordRepository hazardousChemicalsChangeRecordRepository;
    private final LabRepository labRepository;
    private final CabinetRepository cabinetRepository;
    private final MessageRepository messageRepository;
    private final HotHazardousRepository hotHazardousRepository;

    @Override
    public Map<String, Object> queryAll(StorehouseOrderQueryCriteria criteria, Pageable pageable) {
        Page<StorehouseOrder> page = storehouseOrderRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        Page<StorehouseOrderDto> dto = page.map(storehouseOrderMapper::toDto);
        List<StorehouseOrderDto> resultDto = dto.getContent();
        ArrayList<Map> maps = new ArrayList<>();
        for (StorehouseOrderDto storehouseOrderDto : resultDto) {
//            List<Integer> integerList = JSONObject.parseArray(storehouseOrderDto.getData(), Integer.class);
//            for (Integer integer : integerList){
//                StorehouseOrderNumDto storehouseOrderNumDto = new StorehouseOrderNumDto();
//            }
            List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(storehouseOrderDto.getData(), StorehouseOrderNumDto.class);
            for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
                JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class);
                maps.add(JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class));
            }
            String data = JSONObject.toJSONString(storehouseOrderNumDtoList);
            storehouseOrderDto.setStore(maps);
        }
        return PageUtil.toPage(page.map(storehouseOrderMapper::toDto));
    }

    @Override
    public List<StorehouseOrderDto> queryAll(StorehouseOrderQueryCriteria criteria) {
        return storehouseOrderMapper.toDto(storehouseOrderRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public StorehouseOrderDto findById(Integer id) {
        StorehouseOrder storehouseOrder = storehouseOrderRepository.findById(id).orElseGet(StorehouseOrder::new);
        ValidationUtil.isNull(storehouseOrder.getId(), "StorehouseOrder", "id", id);
        return storehouseOrderMapper.toDto(storehouseOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StorehouseOrderDto create(StorehouseOrder resources) {

        return storehouseOrderMapper.toDto(storehouseOrderRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(StorehouseOrder resources) {
        StorehouseOrder storehouseOrder = storehouseOrderRepository.findById(resources.getId()).orElseGet(StorehouseOrder::new);
        ValidationUtil.isNull(storehouseOrder.getId(), "StorehouseOrder", "id", resources.getId());
        storehouseOrder.copy(resources);
        storehouseOrderRepository.save(storehouseOrder);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            storehouseOrderRepository.deleteById(id);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByOrderId(Integer orderId) {
        storehouseOrderRepository.deleteById(orderId);

        int res = storehouseOrderDetailRepository.deleteByOrderId(orderId);
        System.out.println("删除结果" + res);
    }

    @Override
    public void download(List<StorehouseOrderDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (StorehouseOrderDto storehouseOrder : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("申请人", storehouseOrder.getUserName());
            String data = storehouseOrder.getData();
            JSONArray array = JSONUtil.parseArray(data);
            String name = "";
            String num = "";
            String unit = "";
            String detail = "";
            for (int i = 0; i < array.size(); i++) {
                name = array.getJSONObject(i).getStr("name");
                num = array.getJSONObject(i).getStr("num");
                unit = array.getJSONObject(i).getStr("unit");
                detail = (new StringBuilder()).append(detail).append(name).append("x").append(num).append(unit).append(", ").toString();
            }
            detail = detail.substring(0, detail.length() - 2);
            map.put("明细", detail);
            map.put("订单号", storehouseOrder.getNo());
            map.put("申请人备注", storehouseOrder.getNote());
            map.put("时间", storehouseOrder.getCreatedAt());
            String status = "";
            switch (storehouseOrder.getStatus()) {
                case 0:
                    status = "待审批";
                    break;
                case 1:
                    status = "审批中";
                    break;
                case 2:
                    status = "待领取";
                    break;
                case 3:
                    status = "未通过";
                    break;
                case 4:
                    status = "取消";
                    break;
                case 5:
                    status = "已领取";
                    break;
                case 6:
                    status = "归还待审批";
                    break;
            }
            map.put("状态", status);
            map.put("管理员", storehouseOrder.getStorehouseAdminName());
            map.put("主任", storehouseOrder.getDirectorName());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    //领用接口
    @Override
    public Map<String, Object> createOrder(String note, String data) {
        Map<String, Object> tempMap = new HashMap<>();
        List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(data, StorehouseOrderNumDto.class);
        Set<Integer> cabinetIds = new HashSet<>();
        HashMap<Integer, Integer> statusMap = new HashMap<>(); //status 0不审核 1审核
        HashMap<Integer, List<StorehouseOrderNumDto>> integerListHashMap = new HashMap<>();

        for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
            storehouseOrderNumDto.setInventory(1);//1.库存充足 0.库存不足
            storehouseOrderNumDto.setType(hazardousChemicalsTotalRepository.getTypeByName(storehouseOrderNumDto.getName()));
            cabinetIds.add(storehouseOrderNumDto.getCabinetId());
            if (!integerListHashMap.containsKey(storehouseOrderNumDto.getCabinetId())) {
                List<StorehouseOrderNumDto> storehouseOrderNumDtos = new ArrayList<>();
                storehouseOrderNumDtos.add(storehouseOrderNumDto);
                integerListHashMap.put(storehouseOrderNumDto.getCabinetId(), storehouseOrderNumDtos);
            } else {
                List<StorehouseOrderNumDto> storehouseOrderNumDtos = integerListHashMap.get(storehouseOrderNumDto.getCabinetId());
                storehouseOrderNumDtos.add(storehouseOrderNumDto);
                integerListHashMap.put(storehouseOrderNumDto.getCabinetId(), storehouseOrderNumDtos);
            }

            if (!statusMap.containsKey(storehouseOrderNumDto.getCabinetId())) {
                statusMap.put(storehouseOrderNumDto.getCabinetId(), storehouseOrderNumDto.getIsAudit());
            } else {
                if (storehouseOrderNumDto.getIsAudit() == 1) {
                    statusMap.put(storehouseOrderNumDto.getCabinetId(), 1);
                }
            }

            //更新领用热度
            HotHazardous hotHazardous = hotHazardousRepository.findByHcId(storehouseOrderNumDto.getId());
            if (Objects.isNull(hotHazardous)) {
                hotHazardous = new HotHazardous();
                hotHazardous.setCount(1);
                hotHazardous.setHcId(storehouseOrderNumDto.getId());
                hotHazardous.setUserId(Convert.toInt(SecurityUtils.getCurrentUserId()));
            } else {
                hotHazardous.setCount(hotHazardous.getCount() + 1);
            }
            hotHazardousRepository.save(hotHazardous);
        }
        HashMap<Integer, StorehouseOrder> hashMap = new HashMap<>();
        for (Integer i : cabinetIds) {
            StorehouseOrder storehouseOrder = new StorehouseOrder();
            Long userId = SecurityUtils.getCurrentUserId();

            String orderNum = generateOrderNo();
            storehouseOrder.setUserId(Math.toIntExact(userId));
            storehouseOrder.setNo(orderNum);
            storehouseOrder.setNote(note);
            storehouseOrder.setStatus(0);
            if (statusMap.get(i) == 0) {
                storehouseOrder.setStatus(2);
            }
            Cabinet cabinet = cabinetRepository.getById(i);
//            storehouseOrder.setStorehouseAdminId(userRepository.findStorehouseAdminId());
//            storehouseOrder.setDirectorId(userRepository.findDirectorId());
            storehouseOrder.setStorehouseAdminId(cabinet.getStorehouseAdminId());
            storehouseOrder.setDirectorId(cabinet.getDirectorId());
            storehouseOrder = storehouseOrderRepository.save(storehouseOrder);
            tempMap.put("id", storehouseOrder.getId());
            storehouseOrder.setData(com.alibaba.fastjson.JSONArray.toJSONString(integerListHashMap.get(i)));
            hashMap.put(i, storehouseOrder);
        }
        for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
            StorehouseOrderDetail storehouseOrderDetail = new StorehouseOrderDetail();
            storehouseOrderDetail.setGenre(2);
            StorehouseOrder storehouseOrder = hashMap.get(storehouseOrderNumDto.getCabinetId());
            storehouseOrderDetail.setOrderId(storehouseOrder.getId());
            tempMap.put("genre", storehouseOrderDetail.getGenre());

            storehouseOrderDetail.setNum(storehouseOrderNumDto.getNum());//申领数量

            storehouseOrderDetail.setOrderId(storehouseOrder.getId());
            storehouseOrderDetail.setName(storehouseOrderNumDto.getName());
            storehouseOrderDetail.setCountType(1);
            storehouseOrderDetail.setUnit(storehouseOrderNumDto.getUnit());
            storehouseOrderDetail.setCabinetId(storehouseOrderNumDto.getCabinetId());

            storehouseOrderDetail.setNumber(storehouseOrderNumDto.getAmount());

            storehouseOrderDetail.setLabId(storehouseOrderNumDto.getLabId());
            storehouseOrderDetail.setCategory(storehouseOrderNumDto.getCategory());
            storehouseOrderDetail.setType(storehouseOrderNumDto.getType());
            storehouseOrderDetail.setStatus(storehouseOrder.getStatus());
            storehouseOrderDetailRepository.save(storehouseOrderDetail);
        }

        for (Integer i : cabinetIds) {
            if (statusMap.get(i) == 1) {
                //消息
                Cabinet cabinet = cabinetRepository.getById(i);
                Message message = new Message();
                message.setUserId(Math.toIntExact(cabinet.getStorehouseAdminId()));
                message.setUrl("/audit/index");
                message.setName("领用待审批");
                message.setType(2);
                message.setMapId(hashMap.get(i).getId());
                message.setMenuId(6);
                message.setIsRead(0);
                message.setIsDeleted(0);
                messageRepository.save(message);
            } else {
                Message message = new Message();
                message.setUserId(Math.toIntExact(hashMap.get(i).getUserId()));
                message.setUrl("receiveAuth");
                message.setName("领用通知");
                message.setType(2);
                message.setMapId(hashMap.get(i).getId());
                message.setMenuId(6);
                message.setIsRead(0);
                message.setIsDeleted(0);
                messageRepository.save(message);
            }
        }

        return tempMap;
    }


//    @Override
//    public Map<String, Object> createOrder(String note, String data) {
//        Map<String, Object> tempMap = new HashMap<>();
//        StorehouseOrder storehouseOrder = new StorehouseOrder();
//        Long userId = SecurityUtils.getCurrentUserId();
//        String orderNum = getOrderNumber();
//        storehouseOrder.setUserId(Math.toIntExact(userId));
//        storehouseOrder.setNo(orderNum);
//        storehouseOrder.setNote(note);
//        storehouseOrder.setStatus(0);
//        storehouseOrder.setStorehouseAdminId(userRepository.findStorehouseAdminId());
//        storehouseOrder.setDirectorId(userRepository.findDirectorId());
//        ArrayList<StorehouseOrderDetail> storehouseOrderDetails = storehouseOrderDetailRepository.findByOrderId(storehouseOrder.getId());
//        for (StorehouseOrderDetail s : storehouseOrderDetails
//        ) {
//            s.setStatus(storehouseOrder.getStatus());
//        }
//        List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(data, StorehouseOrderNumDto.class);
//        int count = 0;
//        for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
////            storehouseOrderNumDto.setAmount(1f);
////            storehouseOrderNumDto.setNum(1F);
//            storehouseOrderNumDto.setInventory(1);//1.库存充足 0.库存不足
//            storehouseOrderNumDto.setType(hazardousChemicalsTotalRepository.getTypeByName(storehouseOrderNumDto.getName()));
//            if (storehouseOrderNumDto.getIsAudit() == 0) {//todo 判断逻辑有问题，需要从数据库读取
//                count++;
//            }
//        }
//        //如果都不需要审批，则自动审批通过
//        if (count == storehouseOrderNumDtoList.size()) {//审批通过（待领取）
//            storehouseOrder.setStatus(2);
//        }
//        storehouseOrder.setData(JSONObject.toJSONString(storehouseOrderNumDtoList));
//        storehouseOrder = storehouseOrderRepository.save(storehouseOrder);
//        for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
//            StorehouseOrderDetail storehouseOrderDetail = new StorehouseOrderDetail();
//            switch (storehouseOrderNumDto.getType()) {
//                case HazardousChemicals.QI_CAI://器材
//                    switch (storehouseOrderNumDto.getCategory()) {
//                        case "1"://玻璃器皿
//                            storehouseOrderDetail.setGenre(1);//1.一类一码 2.一物一码
//                            break;
//                        case "2"://实验耗材
//                            storehouseOrderDetail.setGenre(1);//1.一类一码 2.一物一码
//                            break;
//                        case "3"://采样工具
//                            storehouseOrderDetail.setGenre(2);//1.一类一码 2.一物一码
//                            break;
//                        case "4"://仪器设备
//                            storehouseOrderDetail.setGenre(2);//1.一类一码 2.一物一码
//                            break;
//                    }
//                    break;
//                case HazardousChemicals.STD_OBJ://标准物质
//                    if ("ml".equalsIgnoreCase(storehouseOrderNumDto.getUnit())) {
//                        storehouseOrderDetail.setGenre(2);// 2.一物一码
//                    } else if ("支".equals(storehouseOrderNumDto.getUnit())) {
//                        storehouseOrderDetail.setGenre(1);//1.一类一码
//                    }
//                    break;
//                case HazardousChemicals.HAZARDOUS_CHEMICALS://化学试剂
//                    storehouseOrderDetail.setGenre(2);//1.一类一码 2.一物一码
//                    break;
//
//            }
//            tempMap.put("genre", storehouseOrderDetail.getGenre());
//
//            storehouseOrderDetail.setNum(storehouseOrderNumDto.getNum());//申领数量
//
//            storehouseOrderDetail.setOrderId(storehouseOrder.getId());
//            storehouseOrderDetail.setName(storehouseOrderNumDto.getName());
//            storehouseOrderDetail.setCountType(1);
//            storehouseOrderDetail.setUnit(storehouseOrderNumDto.getUnit());
//            storehouseOrderDetail.setCabinetId(storehouseOrderNumDto.getCabinetId());
//
//            storehouseOrderDetail.setNumber(storehouseOrderNumDto.getAmount());
//
//            storehouseOrderDetail.setLabId(storehouseOrderNumDto.getLabId());
//            storehouseOrderDetail.setCategory(storehouseOrderNumDto.getCategory());
//            storehouseOrderDetail.setType(storehouseOrderNumDto.getType());
//            storehouseOrderDetail.setStatus(storehouseOrder.getStatus());
//            storehouseOrderDetailRepository.save(storehouseOrderDetail);
//
//        }
//        if (storehouseOrder.getStatus() == 0) {//不自动审批的订单，通知仓库管理员审批
//            List<Integer> directorIds = userRepository.findUserIdsByRoleId(User.ROLE_STORE_HOUSE_ID);
//            for (int directorId : directorIds) {
//                //消息
//                Message message = new Message();
//                message.setUserId(Math.toIntExact(directorId));
//                message.setUrl("/audit/index");
//                message.setName("领用待审批");
//                message.setType(2);
//                message.setMapId(storehouseOrder.getId());
//                message.setMenuId(6);
//                message.setIsRead(0);
//                message.setIsDeleted(0);
//                messageRepository.save(message);
//                //发送短信
//            }
//        } else {//审批通过的订单，通知用户领取
//            Message message = new Message();
//            message.setUserId(Math.toIntExact(storehouseOrder.getUserId()));
//            message.setUrl("receiveAuth");
//            message.setName("领用通知");
//            message.setType(2);
//            message.setMapId(storehouseOrder.getId());
//            message.setMenuId(6);
//            message.setIsRead(0);
//            message.setIsDeleted(0);
//            messageRepository.save(message);
//        }
//        tempMap.put("id", storehouseOrder.getId());
//        return tempMap;
//    }

    @Override
    public void auditOrder(int id, int auditValue, String note) {
        StorehouseOrder storehouseOrder = storehouseOrderRepository.findById(id).orElseGet(StorehouseOrder::new);
        if (storehouseOrder.getStatus() == 0) {//仓库管理员审批
            Long userId = SecurityUtils.getCurrentUserId();
            storehouseOrder.setStorehouseAdminId(Math.toIntExact(userId));
            if (auditValue == 1) {//审批通过
                storehouseOrder.setStatus(1);
                ArrayList<StorehouseOrderDetail> storehouseOrderDetails = storehouseOrderDetailRepository.findByOrderId(storehouseOrder.getId());
                for (StorehouseOrderDetail s : storehouseOrderDetails) {
                    s.setStatus(storehouseOrder.getStatus());
                }
                List<Integer> directorIds = userRepository.findUserIdsByRoleId(User.ROLE_DIRECTOR_ID);
                for (int directorId : directorIds) {
                    //消息
                    Message message = new Message();
                    message.setUserId(Math.toIntExact(directorId));
                    message.setUrl("/audit/index");
                    message.setName("领用待审批");
                    message.setType(2);
                    message.setMapId(storehouseOrder.getId());
                    message.setMenuId(6);
                    message.setIsRead(0);
                    message.setIsDeleted(0);
                    messageRepository.save(message);
                    //发送短信
                }
            } else {
                storehouseOrder.setStatus(3);//未通过
                ArrayList<StorehouseOrderDetail> storehouseOrderDetails = storehouseOrderDetailRepository.findByOrderId(storehouseOrder.getId());
                for (StorehouseOrderDetail s : storehouseOrderDetails
                ) {
                    s.setStatus(storehouseOrder.getStatus());
                }
                storehouseOrder.setStorehouseAdminNote(note);
                //发送消息
                Message message = new Message();
                message.setUserId(Math.toIntExact(storehouseOrder.getUserId()));
                message.setUrl("receiveAuth");
                message.setName("领用审批未通过通知");
                message.setType(2);
                message.setMapId(storehouseOrder.getId());
                message.setMenuId(6);
                message.setIsRead(0);
                message.setIsDeleted(0);
                messageRepository.save(message);
            }
        } else if (storehouseOrder.getStatus() == 1) {//主任审批
            Long userId = SecurityUtils.getCurrentUserId();
            storehouseOrder.setDirectorId(Math.toIntExact(userId));
            if (auditValue == 1) {//审批通过
                storehouseOrder.setStatus(2);
                ArrayList<StorehouseOrderDetail> storehouseOrderDetails = storehouseOrderDetailRepository.findByOrderId(storehouseOrder.getId());
                for (StorehouseOrderDetail s : storehouseOrderDetails
                ) {
                    s.setStatus(storehouseOrder.getStatus());
                }
                //消息
                Message message = new Message();
                message.setUserId(Math.toIntExact(storehouseOrder.getUserId()));
                message.setUrl("receiveAuth");
                message.setName("领用审批通过通知");
                message.setType(2);
                message.setMapId(storehouseOrder.getId());
                message.setMenuId(6);
                message.setIsRead(0);
                message.setIsDeleted(0);
                messageRepository.save(message);

                //开门权限

            } else {
                storehouseOrder.setStatus(3);
                ArrayList<StorehouseOrderDetail> storehouseOrderDetails = storehouseOrderDetailRepository.findByOrderId(storehouseOrder.getId());
                for (StorehouseOrderDetail s : storehouseOrderDetails
                ) {
                    s.setStatus(storehouseOrder.getStatus());
                }
                storehouseOrder.setDirectorNote(note);
                //发送消息
                Message message = new Message();
                message.setUserId(Math.toIntExact(storehouseOrder.getUserId()));
                message.setUrl("receiveAuth");
                message.setName("领用审批未通过通知");
                message.setType(2);
                message.setMapId(storehouseOrder.getId());
                message.setMenuId(6);
                message.setIsRead(0);
                message.setIsDeleted(0);
                messageRepository.save(message);
            }
        }
        storehouseOrderRepository.save(storehouseOrder);
    }

    @Override
    public Map<String, Object> auditOrderList(StorehouseOrderQueryCriteria criteria, Pageable pageable) {
        Integer userId = Convert.toInt(SecurityUtils.getCurrentUserId());
//        List<Integer> roleId = userRepository.getRoleId(userId);
//        if (roleId.contains(4)&&!roleId.contains(5)) {
//            Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
//                List<Predicate> predicates = new ArrayList<Predicate>();
//                if (criteria.getNo() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("no"), criteria.getNo()));
//                }
//                if (criteria.getUserId() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("userId"), criteria.getUserId()));
//                }
//                if (criteria.getCreatedAt() != null) {
//                    predicates.add(criteriaBuilder.between(root.get("createdAt"), criteria.getCreatedAt().get(0), criteria.getCreatedAt().get(1)));
//                }
//                if (criteria.getId() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("id"), criteria.getId()));
//                }
//                predicates.add(criteriaBuilder.equal(root.get("status").as(Integer.class), 0));
//                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
//            };
//            return getStringObjectMap(pageable, specification);
//        }
//        if (roleId.contains(User.ROLE_DIRECTOR_ID)&&!roleId.contains(4)) {
//            Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
//                List<Predicate> predicates = new ArrayList<Predicate>();
//                if (criteria.getNo() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("no").as(Integer.class), criteria.getNo()));
//                }
//                if (criteria.getUserId() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("userId").as(Integer.class), criteria.getUserId()));
//                }
//                if (criteria.getCreatedAt() != null) {
//                    predicates.add(criteriaBuilder.between(root.get("createdAt"), criteria.getCreatedAt().get(0), criteria.getCreatedAt().get(1)));
//                }
//                if (criteria.getId() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("id"), criteria.getId()));
//                }
//                predicates.add(criteriaBuilder.equal(root.get("status").as(Integer.class), 1));
//
//
//                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
//            };
//            return getStringObjectMap(pageable, specification);
//        }
//        if (roleId.contains(User.ROLE_DIRECTOR_ID)&&roleId.contains(4)){
//            Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
//                List<Predicate> predicates = new ArrayList<Predicate>();
//                if (criteria.getNo() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("no"), criteria.getNo()));
//                }
//                if (criteria.getUserId() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("userId"), criteria.getUserId()));
//                }
//                if (criteria.getCreatedAt() != null) {
//                    predicates.add(criteriaBuilder.between(root.get("createdAt"), criteria.getCreatedAt().get(0), criteria.getCreatedAt().get(1)));
//                }
//                if (criteria.getId() != null) {
//                    predicates.add(criteriaBuilder.equal(root.get("id"), criteria.getId()));
//                }
//                predicates.add(criteriaBuilder.or((criteriaBuilder.equal(root.get("status").as(Integer.class), 0)), (criteriaBuilder.equal(root.get("status").as(Integer.class), 1))));
//                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
//            };
//            return getStringObjectMap(pageable, specification);
//        }
//        return null;

        Specification<StorehouseOrder> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (criteria.getNo() != null) {
                predicates.add(criteriaBuilder.equal(root.get("no"), criteria.getNo()));
            }
            if (criteria.getUserId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("userId"), criteria.getUserId()));
            }
            if (criteria.getCreatedAt() != null) {
                predicates.add(criteriaBuilder.between(root.get("createdAt"), criteria.getCreatedAt().get(0), criteria.getCreatedAt().get(1)));
            }
            if (criteria.getId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("id"), criteria.getId()));
            }
            predicates.add(criteriaBuilder.or(criteriaBuilder.and(criteriaBuilder.equal(root.get("status").as(Integer.class), 0), criteriaBuilder.equal(root.get("storehouseAdminId"), userId)), criteriaBuilder.and(criteriaBuilder.equal(root.get("status").as(Integer.class), 1), criteriaBuilder.equal(root.get("directorId"), userId))));

            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        return getStringObjectMap(pageable, specification);
    }

    @Override
    public Map<String, Object> auditOrderPersonalList(StorehouseOrderQueryCriteria criteria, Pageable pageable) {

        Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<Predicate>();

            if (criteria.getStatus() != null) {
                predicates.add(criteriaBuilder.equal(root.get("status"), criteria.getStatus()));
            }
            if (criteria.getData() != null) {
                predicates.add(criteriaBuilder.like(root.get("data"), "%" + criteria.getData() + "%"));
            }

//            if (criteria.getStore()!=null){
//                predicates.add(criteriaBuilder.like(root.get("store"),"%"+criteria.getStore()+"%"));
//            }
            if (criteria.getId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("id"), criteria.getId()));
            }
            if (criteria.getCreatedAt() != null) {
                predicates.add(criteriaBuilder.between(root.get("createdAt"), criteria.getCreatedAt().get(0), criteria.getCreatedAt().get(1)));
            }
            predicates.add(criteriaBuilder.equal(root.get("userId"), SecurityUtils.getCurrentUserId()));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };

//        Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
//            Predicate p1 = criteriaBuilder.equal(root.get("userId").as(Integer.class), SecurityUtils.getCurrentUserId());
//            return criteriaBuilder.and(p1);
//        };
        Page<StorehouseOrder> page = storehouseOrderRepository.findAll(specification, pageable);
        Page<StorehouseOrderDto> dto = page.map(storehouseOrderMapper::toDto);
        List<StorehouseOrderDto> resultDto = dto.getContent();

        List<Long> userIds = new ArrayList<>();
        for (StorehouseOrderDto storehouseOrderDto : resultDto) {
            if (storehouseOrderDto.getStorehouseAdminId() != null) {
                userIds.add((long) storehouseOrderDto.getStorehouseAdminId());
            }
            if (storehouseOrderDto.getDirectorId() != null) {
                userIds.add((long) storehouseOrderDto.getDirectorId());
            }
        }

        List<User> users = userRepository.findAllById(userIds);
        Map<Long, User> userIdToUsers = new HashMap<>();
        for (User user :
                users) {
            userIdToUsers.put(user.getId(), user);
        }
        List<Lab> labs = labRepository.findAll();
        Map<Integer, Lab> idToLab = new HashMap<>();
        for (Lab lab :
                labs) {
            idToLab.put(lab.getId(), lab);
        }
        List<Cabinet> cabinets = cabinetRepository.findAll();
        Map<Integer, Cabinet> idToCabinets = new HashMap<>();
        for (Cabinet cabinet :
                cabinets) {
            idToCabinets.put(cabinet.getId(), cabinet);
        }


        for (StorehouseOrderDto storehouseOrderDto : resultDto) {

            if (storehouseOrderDto.getStorehouseAdminId() != null) {

                if (userIdToUsers.containsKey((long) storehouseOrderDto.getStorehouseAdminId())) {
                    storehouseOrderDto.setStorehouseAdminName(
                            userIdToUsers.get((long) storehouseOrderDto.getStorehouseAdminId()).getUsername()
                    );
                }
            }
            if (storehouseOrderDto.getDirectorId() != null) {
                if (userIdToUsers.containsKey((long) storehouseOrderDto.getDirectorId())) {
                    storehouseOrderDto.setDirectorName(
                            userIdToUsers.get((long) storehouseOrderDto.getDirectorId()).getUsername()
                    );
                }
            }
            List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(storehouseOrderDto.getData(), StorehouseOrderNumDto.class);
            ArrayList<Map> maps = new ArrayList<>();
            for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
                storehouseOrderNumDto.setInventory(judgmentInventory(storehouseOrderNumDto));

                if (idToLab.containsKey(storehouseOrderNumDto.getLabId())) {
                    storehouseOrderNumDto.setLabName(
                            idToLab.get(storehouseOrderNumDto.getLabId()).getName()
                    );
                }

                HazardousChemicals hazardousChemicals = hazardousChemicalsRepository
                        .findByNameAmount(storehouseOrderNumDto.getName(), storehouseOrderNumDto.getAmount());
                if (hazardousChemicals == null) {
                    storehouseOrderNumDto.setCapacity((float) 0);
                } else {
                    storehouseOrderNumDto.setCapacity(hazardousChemicals.getCapacity());
                }

                if (idToCabinets.containsKey(storehouseOrderNumDto.getCabinetId())) {
                    storehouseOrderNumDto.setCabinetName(
                            idToCabinets.get(storehouseOrderNumDto.getCabinetId()).getName()
                    );
                }

                if (storehouseOrderNumDto.getCountType() == 2) {
                    storehouseOrderNumDto.setNum(storehouseOrderNumDto.getAmount());
                }
                JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class);
                maps.add(JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class));
            }
            ArrayList<Map> adminList = new ArrayList<>();
            if (storehouseOrderDto.getStatus() == 0) {
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("name", storehouseOrderDto.getStorehouseAdminName());
                hashMap.put("isPass", 0);
                hashMap.put("resone", storehouseOrderDto.getStorehouseAdminNote());
                adminList.add(hashMap);
                HashMap<String, Object> hashMap1 = new HashMap<>();
                hashMap1.put("name", storehouseOrderDto.getDirectorName());
                hashMap1.put("isPass", 0);
                hashMap1.put("resone", storehouseOrderDto.getDirectorNote());
                adminList.add(hashMap1);
            } else if (storehouseOrderDto.getStatus() == 1) {
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("name", storehouseOrderDto.getStorehouseAdminName());
                hashMap.put("isPass", 2);
                hashMap.put("resone", storehouseOrderDto.getStorehouseAdminNote());
                adminList.add(hashMap);
                HashMap<String, Object> hashMap1 = new HashMap<>();
                hashMap1.put("name", storehouseOrderDto.getDirectorName());
                hashMap1.put("isPass", 0);
                hashMap1.put("resone", storehouseOrderDto.getDirectorNote());
                adminList.add(hashMap1);
            } else if (storehouseOrderDto.getStatus() == 2) {
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("name", storehouseOrderDto.getStorehouseAdminName());
                hashMap.put("isPass", 2);
                hashMap.put("resone", storehouseOrderDto.getStorehouseAdminNote());
                adminList.add(hashMap);
                HashMap<String, Object> hashMap1 = new HashMap<>();
                hashMap1.put("name", storehouseOrderDto.getDirectorName());
                hashMap1.put("isPass", 2);
                hashMap1.put("resone", storehouseOrderDto.getDirectorNote());
                adminList.add(hashMap1);
            } else if (storehouseOrderDto.getStatus() == 3) {
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("name", storehouseOrderDto.getStorehouseAdminName());
                hashMap.put("isPass", 1);
                hashMap.put("resone", storehouseOrderDto.getStorehouseAdminNote());
                adminList.add(hashMap);
                HashMap<String, Object> hashMap1 = new HashMap<>();
                hashMap1.put("name", storehouseOrderDto.getDirectorName());
                hashMap1.put("isPass", 1);
                hashMap1.put("resone", storehouseOrderDto.getDirectorNote());
                adminList.add(hashMap1);
            } else if (storehouseOrderDto.getStatus() == 4) {
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("name", storehouseOrderDto.getStorehouseAdminName());
                hashMap.put("isPass", 0);
                hashMap.put("resone", storehouseOrderDto.getStorehouseAdminNote());
                adminList.add(hashMap);
                HashMap<String, Object> hashMap1 = new HashMap<>();
                hashMap1.put("name", storehouseOrderDto.getDirectorName());
                hashMap1.put("isPass", 0);
                hashMap1.put("resone", storehouseOrderDto.getDirectorNote());
                adminList.add(hashMap1);
            } else {
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("name", storehouseOrderDto.getStorehouseAdminName());
                hashMap.put("isPass", 2);
                hashMap.put("resone", storehouseOrderDto.getStorehouseAdminNote());
                adminList.add(hashMap);
                HashMap<String, Object> hashMap1 = new HashMap<>();
                hashMap1.put("name", storehouseOrderDto.getDirectorName());
                hashMap1.put("isPass", 2);
                hashMap1.put("resone", storehouseOrderDto.getDirectorNote());
                adminList.add(hashMap1);
            }
            String data = JSONObject.toJSONString(storehouseOrderNumDtoList);
            storehouseOrderDto.setData(data);

            storehouseOrderDto.setReviewer(adminList);
            storehouseOrderDto.setStore(maps);
        }
        return PageUtil.toPage(dto);
    }

    //领取
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> delivery(Integer orderId, String data) throws Exception {
        List<DeliveryDto> barCodeList = JSONObject.parseArray(data, DeliveryDto.class);

        for (DeliveryDto deliveryDto : barCodeList) {
            String hc = deliveryDto.getBarCode().replace('h', '0');
            int hcId = Integer.parseInt(hc);
            HazardousChemicals hazardousChemicals = hazardousChemicalsRepository.findByIdAndName(hcId, deliveryDto.getName());
            if (hazardousChemicals == null) {
                throw new RuntimeException(String.format("不存在%s", deliveryDto.getName()));
            }
            float residue = hazardousChemicals.getResidue();
            switch (hazardousChemicals.getType()) {
                case HazardousChemicals.QI_CAI://器材
                    if (hazardousChemicals.getResidue() - deliveryDto.getRealNum() < 0) {

                    }

                    switch (hazardousChemicals.getCategory()) {
                        case "1"://玻璃器皿
                            if (hazardousChemicals.getResidue() - deliveryDto.getRealNum() < 0) {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            if (hazardousChemicals.getAmount() - deliveryDto.getRealNum() < 0) {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            break;
                        case "2"://实验耗材
                            if (hazardousChemicals.getResidue() - deliveryDto.getRealNum() < 0) {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            if (hazardousChemicals.getAmount() - deliveryDto.getRealNum() < 0) {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            break;
                        case "3"://采样工具
                            if (hazardousChemicals.getResidue() - deliveryDto.getRealNum() < 0) {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            break;
                        case "4"://仪器设备
                            if (hazardousChemicals.getResidue() - deliveryDto.getRealNum() < 0) {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            break;
                    }
                    break;
                case HazardousChemicals.BIAO_ZHUN_WU_ZHI://标准物质
                    switch (hazardousChemicals.getUnit()) {
                        case 1://支
                            if (hazardousChemicals.getResidue() >= deliveryDto.getRealNum()) {
                            } else {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            if (hazardousChemicals.getAmount() >= deliveryDto.getRealNum()) {
                            } else {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            break;
                    }
            }
        }


        for (DeliveryDto deliveryDto : barCodeList) {
            String hc = deliveryDto.getBarCode().replace('h', '0');
            int hcId = Integer.parseInt(hc);
            HazardousChemicals hazardousChemicals = hazardousChemicalsRepository.findByIdAndName(hcId, deliveryDto.getName());

            //减少库存
            float residue = hazardousChemicals.getResidue();//库存
            switch (hazardousChemicals.getType()) {
                case HazardousChemicals.QI_CAI://器材
                    if (hazardousChemicals.getResidue() - deliveryDto.getRealNum() < 0) {
                        throw new Exception(String.format("%s库存不足", deliveryDto.getName()));
                    }

                    switch (hazardousChemicals.getCategory()) {
                        case "1"://玻璃器皿
                            hazardousChemicals.setResidue(hazardousChemicals.getResidue() - deliveryDto.getRealNum());
                            hazardousChemicals.setAmount(hazardousChemicals.getAmount() - deliveryDto.getRealNum());
                            break;
                        case "2"://实验耗材
                            hazardousChemicals.setResidue(hazardousChemicals.getResidue() - deliveryDto.getRealNum());
                            hazardousChemicals.setAmount(hazardousChemicals.getAmount() - deliveryDto.getRealNum());
                            break;
                        case "3"://采样工具
                            hazardousChemicals.setResidue(hazardousChemicals.getResidue() - deliveryDto.getRealNum());
                            break;
                        case "4"://仪器设备
                            hazardousChemicals.setResidue(hazardousChemicals.getResidue() - deliveryDto.getRealNum());
                            break;
                    }
                    break;
                case HazardousChemicals.BIAO_ZHUN_WU_ZHI://标准物质
                    switch (hazardousChemicals.getUnit()) {
                        case 1://支
                            if (hazardousChemicals.getResidue() >= deliveryDto.getRealNum()) {
                                hazardousChemicals.setResidue(hazardousChemicals.getResidue() - deliveryDto.getRealNum());
                            } else {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            if (hazardousChemicals.getAmount() >= deliveryDto.getRealNum()) {
                                hazardousChemicals.setAmount(hazardousChemicals.getAmount() - deliveryDto.getRealNum());
                            } else {
                                Map<String, Object> tempMap = new HashMap<>();
                                tempMap.put("name", hazardousChemicals.getName());
                                tempMap.put("amount", hazardousChemicals.getAmount());
                                return tempMap;
                            }
                            break;
                        case 2://瓶
                            hazardousChemicals.setResidue(0f);
                            break;
                    }
                    break;
                case HazardousChemicals.HUA_XUE_SHI_JI://危化品
                    hazardousChemicals.setResidue(0f);
                    break;
            }

            hazardousChemicalsRepository.save(hazardousChemicals);
            HazardousChemicalsTotal hazardousChemicalsTotal;
            hazardousChemicalsTotal = hazardousChemicalsTotalRepository
                    .findByNameAndType(hazardousChemicals.getName(), hazardousChemicals.getType());
//            if (hazardousChemicals.isSTDObj()) {
//                hazardousChemicalsTotal = hazardousChemicalsTotalRepository
//                        .findByNameAndBatchNumberAndType(hazardousChemicals.getName(), hazardousChemicals.getBatchNumber(), hazardousChemicals.getType());
//            } else {
//                hazardousChemicalsTotal = hazardousChemicalsTotalRepository
//                        .findByName(hazardousChemicals.getName());
//            }

            float detailNumber = 0;
            switch (hazardousChemicals.getType()) {
                case HazardousChemicals.QI_CAI://器材
                    switch (hazardousChemicals.getCategory()) {
                        case "1":
                            hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() - deliveryDto.getRealNum());
                            break;
                        case "2":
                            hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() - deliveryDto.getRealNum());
                            break;
                        case "3":
                            hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() - deliveryDto.getRealNum());
                            break;
                        case "4":
                            hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() - deliveryDto.getRealNum());
                            break;
                    }

                    detailNumber = deliveryDto.getRealNum();

                    if (hazardousChemicalsTotal.getTotalNumber() < hazardousChemicalsTotal.getGross() * 0.1) {
                        notifyMessage(hazardousChemicalsTotal, "/Consumable/ConsumableStorehouse");
                    }
                    break;
                case HazardousChemicals.BIAO_ZHUN_WU_ZHI://标准物质
                    switch (hazardousChemicals.getUnit()) {
                        case 1://支
                            hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() - deliveryDto.getRealNum());

                            detailNumber = deliveryDto.getRealNum();
                            break;
                        case 2://瓶
                            hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() - residue);

                            detailNumber = residue;
                            break;
                    }
                    if (hazardousChemicalsTotal.getUnit() == 1) {//支
                        if (hazardousChemicalsTotal.getTotalNumber() < 3) {
                            notifyMessage(hazardousChemicalsTotal, "/standardSubstanceManagement/standardSubstanceStorehouse");
                        }
                    } else if (hazardousChemicalsTotal.getUnit() == 2) {//瓶
                        if (hazardousChemicalsTotal.getTotalNumber() < hazardousChemicalsTotal.getGross() * 0.1) {
                            notifyMessage(hazardousChemicalsTotal, "/standardSubstanceManagement/standardSubstanceStorehouse");
                        }
                    }
                    break;
                case HazardousChemicals.HUA_XUE_SHI_JI://化学试剂
                    hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() - residue);

                    detailNumber = residue;

                    if (hazardousChemicalsTotal.getTotalNumber() < hazardousChemicalsTotal.getGross() * 0.1) {
                        notifyMessage(hazardousChemicalsTotal, "/standardSubstanceManagement/standardSubstanceStorehouse");
                    }
                    break;
            }

            hazardousChemicalsTotalRepository.save(hazardousChemicalsTotal);

            //修改明细表
            StorehouseOrderDetail storehouseOrderDetail = storehouseOrderDetailRepository
                    .getByNameAndOrderIdToBeApply(hazardousChemicals.getName(), orderId);
            if (storehouseOrderDetail == null) {
                storehouseOrderDetail = storehouseOrderDetailRepository
                        .getByNameAndOrderIdApplied(hazardousChemicals.getName(), orderId);

                if (storehouseOrderDetail == null) {
                    throw new Exception(hazardousChemicals.getName() + " 未进行申领");
                }

                storehouseOrderDetail = JSON.parseObject(JSON.toJSONString(storehouseOrderDetail), StorehouseOrderDetail.class);
                //如果没有找到记录的话，新增一条
                storehouseOrderDetail.setId(null);
            }

            storehouseOrderDetail.setHjHazardousChemicalId(hazardousChemicals.getId());
            storehouseOrderDetail.setRealNum(deliveryDto.getRealNum());
            storehouseOrderDetail.setClaimDetailNumber(detailNumber);

            storehouseOrderDetailRepository.save(storehouseOrderDetail);

            //变更记录
            HazardousChemicalsChangeRecord hazardousChemicalsChangeRecord = new HazardousChemicalsChangeRecord();
            hazardousChemicalsChangeRecord.setOrderId(orderId);//订单ID
            hazardousChemicalsChangeRecord.setUserId(Convert.toInt(SecurityUtils.getCurrentUserId()));
            hazardousChemicalsChangeRecord.setDetailNumber(detailNumber);//详细数量
            hazardousChemicalsChangeRecord.setHcId(hazardousChemicals.getId());
            hazardousChemicalsChangeRecord.setName(hazardousChemicals.getName());

            if (hazardousChemicals.isSingleCodePerObject()) {//一物一码，都是按1瓶领取
                hazardousChemicalsChangeRecord.setAmount(1f);//领用数量
            } else {
                hazardousChemicalsChangeRecord.setAmount(deliveryDto.getRealNum());//领用数量
            }

            hazardousChemicalsChangeRecord.setType(hazardousChemicals.getType());
            hazardousChemicalsChangeRecord.setBatchNumber(hazardousChemicals.getBatchNumber());
            hazardousChemicalsChangeRecord.setNumber(hazardousChemicals.getNumber());//编号
            hazardousChemicalsChangeRecord.setIngredientData(hazardousChemicals.getIngredientData());
            hazardousChemicalsChangeRecord.setMatrix(hazardousChemicals.getMatrix());
            hazardousChemicalsChangeRecord.setExpirationDate(hazardousChemicals.getExpirationDate());
            hazardousChemicalsChangeRecord.setState(HazardousChemicalsChangeRecord.STATE_OUTPUT);//出库
            hazardousChemicalsChangeRecord.setCountType(hazardousChemicals.getCountType());
            hazardousChemicalsChangeRecordRepository.save(hazardousChemicalsChangeRecord);
        }

        StorehouseOrder storehouseOrder = storehouseOrderRepository.findById(orderId).orElseGet(StorehouseOrder::new);
        storehouseOrder.setStatus(StorehouseOrder.STATUS_YI_LING_QU);
        ArrayList<StorehouseOrderDetail> storehouseOrderDetails = storehouseOrderDetailRepository.findByOrderId(storehouseOrder.getId());
        for (StorehouseOrderDetail storehouseOrderDetail : storehouseOrderDetails
        ) {
            storehouseOrderDetail.setStatus(StorehouseOrder.STATUS_YI_LING_QU);
            storehouseOrderDetailRepository.save(storehouseOrderDetail);
        }

        return new HashMap<>();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deliveryByScan(int userId, List<Integer> ids) throws Exception {
        List<HazardousChemicals> hazardousChemicalses = hazardousChemicalsRepository.findAllById(ids);
        if (hazardousChemicalses.size() != ids.size()) {
            throw new Exception("参数错误，部分id未找到对应的物品");
        }

        //修改明细表
        StorehouseOrder order = new StorehouseOrder();
        order.setUserId(userId);
        order.setNo(generateOrderNo());
        order.setStatus(StorehouseOrder.STATUS_YI_LING_QU);
        List<Integer> adminIds = userRepository.findStorehouseAdminIds();
        order.setStorehouseAdminId(adminIds.get(0));

        List<Integer> directorIds = userRepository.findDirectorIds();
        order.setDirectorId(directorIds.get(0));
        order.setData(com.alibaba.fastjson.JSONArray.toJSONString(ids));

        storehouseOrderRepository.save(order);
        for (HazardousChemicals hazardousChemicals : hazardousChemicalses) {
            StorehouseOrderDetail orderDetail = new StorehouseOrderDetail();
            orderDetail.setGenre(StorehouseOrderDetail.GENRE_YI_PING_YI_MA);
            orderDetail.setOrderId(order.getId());

            orderDetail.setNum(hazardousChemicals.getResidue());//申领数量
            orderDetail.setOrderId(order.getId());
            orderDetail.setHjHazardousChemicalId(hazardousChemicals.getId());

            orderDetail.setName(hazardousChemicals.getName());
            orderDetail.setCountType(1);

            HazardousChemicalsDto hazardousChemicalsDto = hazardousChemicalsMapper.toDto(hazardousChemicals);
            hazardousChemicalsDto.parseInfo();

            orderDetail.setUnit(hazardousChemicalsDto.getUnitStr());

            orderDetail.setCabinetId(hazardousChemicals.getCabinetId());

            orderDetail.setNumber(hazardousChemicals.getResidue());
            orderDetail.setRealNum(hazardousChemicals.getResidue());
            orderDetail.setClaimDetailNumber(hazardousChemicals.getResidue());
            orderDetail.setReturnDetailNumber(0f);

            orderDetail.setLabId(hazardousChemicals.getLabId());
            orderDetail.setCategory(hazardousChemicals.getCategory());
            orderDetail.setType(hazardousChemicals.getType());
            orderDetail.setStatus(order.getStatus());
            storehouseOrderDetailRepository.save(orderDetail);
        }

        for (HazardousChemicals hazardousChemicals : hazardousChemicalses) {
            //总库存表
            HazardousChemicalsTotal hazardousChemicalsTotal = hazardousChemicalsTotalRepository
                    .findByNameAndType(hazardousChemicals.getName(), hazardousChemicals.getType());

            //减少库存
            float changeNumber = 0;//变更数量

            switch (hazardousChemicals.getType()) {
                case HazardousChemicals.QI_CAI://器材
                    hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() - 1);
                    changeNumber = 1;
                    hazardousChemicals.setResidue(0f);

                    if (hazardousChemicalsTotal.getTotalNumber() < hazardousChemicalsTotal.getGross() * 0.1) {
                        notifyMessage(hazardousChemicalsTotal, "/Consumable/ConsumableStorehouse");
                    }
                    break;
                case HazardousChemicals.BIAO_ZHUN_WU_ZHI://标准物质
                    switch (hazardousChemicals.getUnit()) {
                        case 1://支
                            changeNumber = 1;
                            hazardousChemicals.setResidue(0f);
                            hazardousChemicals.setAmount(0f);
                            break;
                        case 2://瓶
                            changeNumber = hazardousChemicals.getResidue();
                            hazardousChemicals.setResidue(0f);
                            hazardousChemicals.setAmount(0f);
                            break;
                    }

                    if (hazardousChemicalsTotal.getUnit() == 1) {//支
                        if (hazardousChemicalsTotal.getTotalNumber() < 3) {
                            notifyMessage(hazardousChemicalsTotal, "/standardSubstanceManagement/standardSubstanceStorehouse");
                        }
                    } else if (hazardousChemicalsTotal.getUnit() == 2) {//瓶
                        if (hazardousChemicalsTotal.getTotalNumber() < hazardousChemicalsTotal.getGross() * 0.1) {
                            notifyMessage(hazardousChemicalsTotal, "/standardSubstanceManagement/standardSubstanceStorehouse");
                        }
                    }
                    break;
                case HazardousChemicals.HUA_XUE_SHI_JI://化学试剂
                    changeNumber = hazardousChemicals.getResidue();
                    hazardousChemicals.setResidue(0f);
                    hazardousChemicals.setAmount(0f);

                    if (hazardousChemicalsTotal.getTotalNumber() < hazardousChemicalsTotal.getGross() * 0.1) {
                        notifyMessage(hazardousChemicalsTotal, "/standardSubstanceManagement/standardSubstanceStorehouse");
                    }
                    break;
            }

            //更新单表
            hazardousChemicalsRepository.save(hazardousChemicals);
            //更新统计表
            hazardousChemicalsTotalRepository.save(hazardousChemicalsTotal);

            //变更记录
            HazardousChemicalsChangeRecord hazardousChemicalsChangeRecord = new HazardousChemicalsChangeRecord();
            hazardousChemicalsChangeRecord.setOrderId(order.getId());//订单ID
            hazardousChemicalsChangeRecord.setUserId(userId);
            hazardousChemicalsChangeRecord.setDetailNumber(changeNumber);//详细数量
            hazardousChemicalsChangeRecord.setHcId(hazardousChemicals.getId());
            hazardousChemicalsChangeRecord.setName(hazardousChemicals.getName());
            hazardousChemicalsChangeRecord.setAmount(1f);//领用数量

            hazardousChemicalsChangeRecord.setType(hazardousChemicals.getType());
            hazardousChemicalsChangeRecord.setBatchNumber(hazardousChemicals.getBatchNumber());
            hazardousChemicalsChangeRecord.setNumber(hazardousChemicals.getNumber());//编号
            hazardousChemicalsChangeRecord.setIngredientData(hazardousChemicals.getIngredientData());
            hazardousChemicalsChangeRecord.setMatrix(hazardousChemicals.getMatrix());
            hazardousChemicalsChangeRecord.setExpirationDate(hazardousChemicals.getExpirationDate());

            hazardousChemicalsChangeRecord.setState(HazardousChemicalsChangeRecord.STATE_OUTPUT);//出库
            hazardousChemicalsChangeRecord.setCountType(hazardousChemicals.getCountType());
            //领取操作
            hazardousChemicalsChangeRecord.setLqNumber(changeNumber);//领取量
            hazardousChemicalsChangeRecord.setIsReturn(1);//设置状态为未归还状态

            hazardousChemicalsChangeRecordRepository.save(hazardousChemicalsChangeRecord);
        }
    }


    void notifyMessage(HazardousChemicalsTotal tmpHazardousChemicalsTotal, String url) {
        for (Integer userId : userRepository.findUserIdsByRoleId(4)) {
            Message message = new Message();
            message.setUserId(userId);
            message.setMenuId(6);
            message.setIsRead(0);
            message.setMapId(tmpHazardousChemicalsTotal.getId());
            message.setName(tmpHazardousChemicalsTotal.getName() + "库存不足。");
            message.setType(2);
            message.setUrl(url);
            messageRepository.save(message);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(Integer id) {
        StorehouseOrder storehouseOrder = storehouseOrderRepository.findById(id).orElseGet(StorehouseOrder::new);
        storehouseOrder.setStatus(4);
        ArrayList<StorehouseOrderDetail> storehouseOrderDetails = storehouseOrderDetailRepository.findByOrderId(storehouseOrder.getId());
        for (StorehouseOrderDetail s : storehouseOrderDetails
        ) {
            s.setStatus(storehouseOrder.getStatus());
            storehouseOrderDetailRepository.save(s);
        }
        storehouseOrderRepository.save(storehouseOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void giveBack(Integer id, String data) throws Exception {
        StorehouseOrder storehouseOrder = storehouseOrderRepository.findById(id).orElseGet(StorehouseOrder::new);
        storehouseOrder.setStatus(6);//已归还
        ArrayList<StorehouseOrderDetail> storehouseOrderDetails = storehouseOrderDetailRepository.findByOrderId(storehouseOrder.getId());
        for (StorehouseOrderDetail storehouseOrderDetail : storehouseOrderDetails
        ) {
            storehouseOrderDetail.setStatus(storehouseOrder.getStatus());
            storehouseOrderDetailRepository.save(storehouseOrderDetail);
        }
        storehouseOrderRepository.save(storehouseOrder);

        //JSONObject jsonObject = JSONObject.parseObject(data);//从请求体里获得jsonObject
        //String GiveBackDtoString = jsonObject.getString("data");//解析成字符串
        List<GiveBackDto> giveBackDtoList = JSONObject.parseArray(data, GiveBackDto.class);
        for (GiveBackDto giveBackDto : giveBackDtoList) {
            if (giveBackDto.getBarCode() != null && !giveBackDto.getBarCode().equals("") && giveBackDto.getBarCode().length() > 0) {
                String hc = giveBackDto.getBarCode();
                hc = hc.replace('h', '0');
//                hc = hc.replaceAll("^(0+)", "");
                int hcId = Integer.parseInt(hc);
                HazardousChemicals hazardousChemicals = hazardousChemicalsRepository.findById(hcId).orElseGet(HazardousChemicals::new);
                hazardousChemicals.setStatus(0);//已入库
                if (hazardousChemicals.isQiCai()) {
                    hazardousChemicals.setResidue(1f);//剩余量
                } else if (hazardousChemicals.isBiaoZhunWuZhi()) {
                    hazardousChemicals.setResidue(giveBackDto.getBackAmount());
                } else if (hazardousChemicals.isHuaXueShiJi()) {
                    hazardousChemicals.setResidue(giveBackDto.getBackAmount());
                }

                //amount  瓶
                hazardousChemicals.setAmount(giveBackDto.getBackAmount());

                hazardousChemicals = hazardousChemicalsRepository.save(hazardousChemicals);
                HazardousChemicalsTotal hazardousChemicalsTotal = hazardousChemicalsTotalRepository.findByNameAmountLabCabinet(
                        hazardousChemicals.getName(),
                        hazardousChemicals.getAmount(),
                        hazardousChemicals.getLabId(),
                        hazardousChemicals.getCabinetId(),
                        hazardousChemicals.getType(),
                        hazardousChemicals.getCountType()
                );

                if (hazardousChemicalsTotal != null) {
                    hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() + giveBackDto.getBackAmount());
                    hazardousChemicalsTotalRepository.save(hazardousChemicalsTotal);
                } else {
                    HazardousChemicalsTotal hazardousChemicalsTotal1 = new HazardousChemicalsTotal();
                    hazardousChemicalsTotal1.setTotalNumber(giveBackDto.getBackAmount());
                    hazardousChemicalsTotal1.setType(hazardousChemicals.getType());
                    hazardousChemicalsTotal1.setDangerClasses(hazardousChemicals.getDangerClasses());
                    hazardousChemicalsTotal1.setLabId(hazardousChemicals.getLabId());
                    hazardousChemicalsTotal1.setAmount(1);
                    hazardousChemicalsTotal1.setName(hazardousChemicals.getName());
                    hazardousChemicalsTotal1.setCabinetId(hazardousChemicals.getCabinetId());
                    hazardousChemicalsTotal1.setCountType(hazardousChemicals.getCountType());
                    hazardousChemicalsTotalRepository.save(hazardousChemicalsTotal1);
                }

                HazardousChemicalsChangeRecord hazardousChemicalsChangeRecord = new HazardousChemicalsChangeRecord();
                hazardousChemicalsChangeRecord.setCountType(hazardousChemicals.getCountType());
                hazardousChemicalsChangeRecord.setUserId(Convert.toInt(SecurityUtils.getCurrentUserId()));
                hazardousChemicalsChangeRecord.setType(hazardousChemicals.getType());
                hazardousChemicalsChangeRecord.setName(hazardousChemicals.getName());

                if (hazardousChemicals.isSingleCodePerObject()) {//一物一码，都是按1瓶领取
                    hazardousChemicalsChangeRecord.setAmount(1f);//
                } else {
                    hazardousChemicalsChangeRecord.setAmount(hazardousChemicals.getAmount());//
                }

                hazardousChemicalsChangeRecord.setCountType(hazardousChemicals.getCountType());
                hazardousChemicalsChangeRecord.setHcId(hazardousChemicals.getId());
                hazardousChemicalsChangeRecord.setState(3);

                hazardousChemicalsChangeRecord.setBatchNumber(hazardousChemicals.getBatchNumber());
                hazardousChemicalsChangeRecord.setNumber(hazardousChemicals.getNumber());//编号
                hazardousChemicalsChangeRecord.setIngredientData(hazardousChemicals.getIngredientData());
                hazardousChemicalsChangeRecord.setMatrix(hazardousChemicals.getMatrix());
                hazardousChemicalsChangeRecord.setExpirationDate(hazardousChemicals.getExpirationDate());

                hazardousChemicalsChangeRecordRepository.save(hazardousChemicalsChangeRecord);
            } else {
                throw new Exception("条码格式错误");
            }
        }
    }

    @Override
    public Map<String, Object> recordList(StorehouseOrderQueryCriteria criteria, Pageable pageable) {
        Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<Predicate>();
            if (criteria.getNo() != null) {
                predicates.add(criteriaBuilder.equal(root.get("no"), criteria.getNo()));
            }
            if (criteria.getUserId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("userId"), criteria.getUserId()));
            }
            if (criteria.getCreatedAt() != null) {
                predicates.add(criteriaBuilder.between(root.get("createdAt"), criteria.getCreatedAt().get(0), criteria.getCreatedAt().get(1)));
            }
            if (criteria.getId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("id"), criteria.getId()));
            }
            if (criteria.getStatus() != null) {
                predicates.add(criteriaBuilder.equal(root.get("status"), criteria.getStatus()));
            }
//            predicates.add(criteriaBuilder.equal(root.get("status").as(Integer.class), 0));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<StorehouseOrder> page = storehouseOrderRepository.findAll(specification, pageable);
        Page<StorehouseOrderDto> dto = page.map(storehouseOrderMapper::toDto);
        List<StorehouseOrderDto> resultDto = dto.getContent();

        for (StorehouseOrderDto storehouseOrderDto : resultDto) {

            if (storehouseOrderDto.getStorehouseAdminId() != null) {
                User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getStorehouseAdminId())).orElseGet(User::new);
                storehouseOrderDto.setStorehouseAdminName(user.getUsername());
            }
            if (storehouseOrderDto.getDirectorId() != null) {
                User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getDirectorId())).orElseGet(User::new);
                storehouseOrderDto.setDirectorName(user.getUsername());
            }
            User creator = userRepository.findById(Long.valueOf(storehouseOrderDto.getUserId())).orElseGet(User::new);
            storehouseOrderDto.setUserName(creator.getUsername());
            if (storehouseOrderDto.getData() != null) {
                List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSON.parseArray(storehouseOrderDto.getData(), StorehouseOrderNumDto.class);
                ArrayList<Map> maps = new ArrayList<>();
                for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
                    storehouseOrderNumDto.setInventory(judgmentInventory(storehouseOrderNumDto));
                    Lab lab = labRepository.findById(storehouseOrderNumDto.getLabId()).orElseGet(Lab::new);
                    storehouseOrderNumDto.setLabName(lab.getName());
                    Cabinet cabinet = cabinetRepository.findById(storehouseOrderNumDto.getCabinetId()).orElseGet(Cabinet::new);
                    storehouseOrderNumDto.setCabinetName(cabinet.getName());
                    if (storehouseOrderNumDto.getCountType() == 2) {
                        storehouseOrderNumDto.setNum(storehouseOrderNumDto.getAmount());
                    }
                    JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class);
                    maps.add(JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class));
                }
                String data = JSONObject.toJSONString(storehouseOrderNumDtoList);

                storehouseOrderDto.setStore(maps);
            }
        }
        return PageUtil.toPage(dto);
    }

    @Override
    public Map<String, Object> giveBackList(StorehouseOrderQueryCriteria criteria, Pageable pageable) {
        Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<Predicate>();
            predicates.add(criteriaBuilder.equal(root.get("status").as(Integer.class), 5));
            if (criteria.getCreatedAt() != null) {
                predicates.add(criteriaBuilder.between(root.get("createdAt"), criteria.getCreatedAt().get(0), criteria.getCreatedAt().get(1)));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<StorehouseOrder> page = storehouseOrderRepository.findAll(specification, pageable);

        Page<StorehouseOrderDto> dto = page.map(storehouseOrderMapper::toDto);
        List<StorehouseOrderDto> resultDto = dto.getContent();

        for (StorehouseOrderDto storehouseOrderDto : resultDto) {

            if (storehouseOrderDto.getStorehouseAdminId() != null) {
                User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getStorehouseAdminId())).orElseGet(User::new);
                storehouseOrderDto.setStorehouseAdminName(user.getUsername());
            }
            if (storehouseOrderDto.getDirectorId() != null) {
                User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getDirectorId())).orElseGet(User::new);
                storehouseOrderDto.setDirectorName(user.getUsername());
            }
            User creator = userRepository.findById(Long.valueOf(storehouseOrderDto.getUserId())).orElseGet(User::new);
            storehouseOrderDto.setUserName(creator.getUsername());
            List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(storehouseOrderDto.getData(), StorehouseOrderNumDto.class);
            ArrayList<Map> maps = new ArrayList<>();
            for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
                storehouseOrderNumDto.setInventory(judgmentInventory(storehouseOrderNumDto));
                Lab lab = labRepository.findById(storehouseOrderNumDto.getLabId()).orElseGet(Lab::new);
                storehouseOrderNumDto.setLabName(lab.getName());
                Cabinet cabinet = cabinetRepository.findById(storehouseOrderNumDto.getCabinetId()).orElseGet(Cabinet::new);
                storehouseOrderNumDto.setCabinetName(cabinet.getName());

                JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class);
                maps.add(JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class));
            }
            storehouseOrderDto.setDetailList(storehouseOrderDetailRepository.findAllByOrderId(storehouseOrderDto.getId()));
            storehouseOrderDto.setStore(maps);
        }
        return PageUtil.toPage(dto);
    }

    @Override
    public Map<String, Object> deliveryList(StorehouseOrderQueryCriteria criteria, Pageable pageable) {
        Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<Predicate>();
            predicates.add(criteriaBuilder.equal(root.get("status"), 2));
            predicates.add(criteriaBuilder.equal(root.get("userId"), SecurityUtils.getCurrentUserId()));


            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<StorehouseOrder> page = storehouseOrderRepository.findAll(specification, pageable);

        Page<StorehouseOrderDto> dto = page.map(storehouseOrderMapper::toDto);
        List<StorehouseOrderDto> resultDto = dto.getContent();

        for (StorehouseOrderDto storehouseOrderDto : resultDto) {

            if (storehouseOrderDto.getStorehouseAdminId() != null) {
                User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getStorehouseAdminId())).orElseGet(User::new);
                storehouseOrderDto.setStorehouseAdminName(user.getUsername());
            }
            if (storehouseOrderDto.getDirectorId() != null) {
                User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getDirectorId())).orElseGet(User::new);
                storehouseOrderDto.setDirectorName(user.getUsername());
            }
            User creator = userRepository.findById(Long.valueOf(storehouseOrderDto.getUserId())).orElseGet(User::new);
            storehouseOrderDto.setUserName(creator.getUsername());
            List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(storehouseOrderDto.getData(), StorehouseOrderNumDto.class);
            ArrayList<Map> maps = new ArrayList<>();
            for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
                storehouseOrderNumDto.setInventory(judgmentInventory(storehouseOrderNumDto));
                Lab lab = labRepository.findById(storehouseOrderNumDto.getLabId()).orElseGet(Lab::new);
                storehouseOrderNumDto.setLabName(lab.getName());
                Cabinet cabinet = cabinetRepository.findById(storehouseOrderNumDto.getCabinetId()).orElseGet(Cabinet::new);
                storehouseOrderNumDto.setCabinetName(cabinet.getName());
                JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class);
                maps.add(JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class));
            }
            String data = JSONObject.toJSONString(storehouseOrderNumDtoList);
            storehouseOrderDto.setStore(maps);
        }
        return PageUtil.toPage(dto);
    }

    @Override
    public List<StorehouseOrderDetail> hcList(Integer id, Integer cabinetId) {
        return storehouseOrderDetailRepository.findBySid(id, cabinetId);
    }

//    @Override
//    public Map<String, Object> returnHcList(StorehouseOrderQueryCriteria criteria, Pageable pageable) {
//        List<Integer> idList = storehouseOrderDetailRepository.findHcId();
//        ArrayList<HazardousChemicals> hazardousChemicalsArrayList = new ArrayList<>();
//        for (Integer hcId : idList) {
//            HazardousChemicals hazardousChemicals = hazardousChemicalsRepository.findById(hcId).orElseGet(HazardousChemicals::new);
//            StorehouseOrderDetail storehouseOrderDetail = storehouseOrderDetailRepository.findByHcId(hcId);
//            StorehouseOrder storehouseOrder = storehouseOrderRepository.findById(storehouseOrderDetail.getOrderId()).orElseGet(StorehouseOrder::new);
//            if (hazardousChemicals.getType() == 1 && Objects.equals(hazardousChemicals.getCategory(), "1") && storehouseOrder.getStatus() == 5
//                    || hazardousChemicals.getType() == 1 && Objects.equals(hazardousChemicals.getCategory(), "1") && storehouseOrder.getStatus() == 6
//                    || hazardousChemicals.getType() == 1 && Objects.equals(hazardousChemicals.getCategory(), "2") && storehouseOrder.getStatus() == 5
//                    || hazardousChemicals.getType() == 1 && Objects.equals(hazardousChemicals.getCategory(), "2") && storehouseOrder.getStatus() == 6
//            ) {
//
//            }
//        }
//        return null;
//    }

    @Override
    public List<StorehouseOrderDto> recordList(StorehouseOrderQueryCriteria criteria) {
        Specification<StorehouseOrder> specification = (Specification<StorehouseOrder>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<Predicate>();
            if (criteria.getNo() != null) {
                predicates.add(criteriaBuilder.equal(root.get("no"), criteria.getNo()));
            }
            if (criteria.getUserId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("userId"), criteria.getUserId()));
            }
            if (criteria.getCreatedAt() != null) {
                predicates.add(criteriaBuilder.between(root.get("createdAt"), criteria.getCreatedAt().get(0), criteria.getCreatedAt().get(1)));
            }
            if (criteria.getId() != null) {
                predicates.add(criteriaBuilder.equal(root.get("id"), criteria.getId()));
            }
//
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        List<StorehouseOrder> storehouseOrderList = storehouseOrderRepository.findAll(specification);
        List<StorehouseOrderDto> storehouseOrderDtoList = storehouseOrderMapper.toDto(storehouseOrderList);

        for (StorehouseOrderDto storehouseOrderDto : storehouseOrderDtoList) {
            if (storehouseOrderDto.getStorehouseAdminId() != null) {
                User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getStorehouseAdminId())).orElseGet(User::new);
                storehouseOrderDto.setStorehouseAdminName(user.getUsername());
            }
            if (storehouseOrderDto.getDirectorId() != null) {
                User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getDirectorId())).orElseGet(User::new);
                storehouseOrderDto.setDirectorName(user.getUsername());
            }
            User creator = userRepository.findById(Long.valueOf(storehouseOrderDto.getUserId())).orElseGet(User::new);
            storehouseOrderDto.setUserName(creator.getUsername());
            List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(storehouseOrderDto.getData(), StorehouseOrderNumDto.class);
            ArrayList<Map> maps = new ArrayList<>();
            for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
                storehouseOrderNumDto.setInventory(judgmentInventory(storehouseOrderNumDto));
                Lab lab = labRepository.findById(storehouseOrderNumDto.getLabId()).orElseGet(Lab::new);
                storehouseOrderNumDto.setLabName(lab.getName());
                Cabinet cabinet = cabinetRepository.findById(storehouseOrderNumDto.getCabinetId()).orElseGet(Cabinet::new);
                storehouseOrderNumDto.setCabinetName(cabinet.getName());
                if (storehouseOrderNumDto.getCountType() == 2) {
                    storehouseOrderNumDto.setNum(storehouseOrderNumDto.getAmount());
                }
                JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class);
                maps.add(JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class));
            }

            storehouseOrderDto.setStore(maps);
        }
        return storehouseOrderDtoList;
    }

    @Override
    public List<StorehouseOrderDto> deliveryListAndroid(String cabinetIds) {
        String[] cabinetList = cabinetIds.split(",");
        int[] cabinetIdList = new int[cabinetList.length];
        for (int i = 0; i < cabinetList.length; i++) {
            cabinetIdList[i] = Integer.parseInt(cabinetList[i]);
        }
        List<StorehouseOrder> storehouseOrderList;
        List<Integer> orderIds = storehouseOrderDetailRepository.findToBeDeliveredOrderIdByCabinetIds(cabinetIdList);

        storehouseOrderList = storehouseOrderRepository.findAllById(orderIds);

        List<StorehouseOrderDto> storehouseOrderDtos = storehouseOrderMapper.toDto(storehouseOrderList);

        List<Long> userIds = new ArrayList<>();

        for (StorehouseOrderDto storehouseOrderDto : storehouseOrderDtos) {
            if (storehouseOrderDto.getStorehouseAdminId() > 0) {
                userIds.add((long) storehouseOrderDto.getStorehouseAdminId());
            }
            if (storehouseOrderDto.getDirectorId() > 0) {
                userIds.add((long) storehouseOrderDto.getDirectorId());
            }
            if (storehouseOrderDto.getUserId() > 0) {
                userIds.add((long) storehouseOrderDto.getUserId());
            }
        }
        List<User> users = userRepository.findAllById(userIds);
        Map<Long, User> userIdToUsers = new HashMap<>();
        for (User user :
                users) {
            userIdToUsers.put(user.getId(), user);
        }
        List<Lab> labs = labRepository.findAll();
        Map<Integer, Lab> idToLab = new HashMap<>();
        for (Lab lab :
                labs) {
            idToLab.put(lab.getId(), lab);
        }
        List<Cabinet> cabinets = cabinetRepository.findAll();
        Map<Integer, Cabinet> idToCabinets = new HashMap<>();
        for (Cabinet cabinet :
                cabinets) {
            idToCabinets.put(cabinet.getId(), cabinet);
        }

        List<StorehouseOrderNumDto> storehouseOrderNumDtos = new ArrayList<>();

        for (StorehouseOrderDto storehouseOrderDto : storehouseOrderDtos) {

            if (storehouseOrderDto.getStorehouseAdminId() != null) {
                if (userIdToUsers.containsKey((long) storehouseOrderDto.getStorehouseAdminId())) {
                    storehouseOrderDto.setStorehouseAdminName(
                            userIdToUsers.get((long) storehouseOrderDto.getStorehouseAdminId()).getUsername()
                    );
                }
            }
            if (storehouseOrderDto.getDirectorId() != null) {
                if (userIdToUsers.containsKey((long) storehouseOrderDto.getDirectorId())) {
                    storehouseOrderDto.setDirectorName(
                            userIdToUsers.get((long) storehouseOrderDto.getDirectorId()).getUsername()
                    );
                }
            }

            if (userIdToUsers.containsKey((long) storehouseOrderDto.getUserId())) {
                storehouseOrderDto.setUserName(
                        userIdToUsers.get((long) storehouseOrderDto.getUserId()).getUsername()
                );
            } else {
                storehouseOrderDto.setUserName("-");
            }
            List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(
                    storehouseOrderDto.getData(),
                    StorehouseOrderNumDto.class
            );

            List<StorehouseOrderNumDto> dtos = new ArrayList<>();

            for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
                storehouseOrderNumDtos.add(storehouseOrderNumDto);

                if (!Arrays.asList(cabinetList).contains(Convert.toStr(storehouseOrderNumDto.getCabinetId()))) {
                    continue;
                }
                if (idToLab.containsKey(storehouseOrderNumDto.getLabId())) {
                    storehouseOrderNumDto.setLabName(
                            idToLab.get(storehouseOrderNumDto.getLabId()).getName()
                    );
                }
                if (idToCabinets.containsKey(storehouseOrderNumDto.getCabinetId())) {
                    storehouseOrderNumDto.setCabinetName(
                            idToCabinets.get(storehouseOrderNumDto.getCabinetId()).getName()
                    );
                }

                dtos.add(storehouseOrderNumDto);
            }

            storehouseOrderDto.setStore(dtos);
        }

        judgmentInventory(storehouseOrderNumDtos);

        return storehouseOrderDtos;
    }

    @Override
    public List<StorehouseOrder> findByUserIdAndStatus(int userId, int status) {
        List<StorehouseOrder> orders = storehouseOrderRepository.findByUserIdAndStatus(userId, status);

        for (StorehouseOrder order : orders) {
            order.setDetails(storehouseOrderDetailRepository.findByOrderId(order.getId()));
        }
        return orders;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doReturn(Integer userId, Integer orderId, List<Integer> orderDetailIds, List<Integer> returnNumbers) throws Exception {
        StorehouseOrder storehouseOrder = storehouseOrderRepository.getById(orderId);
        if (orderDetailIds.size() != returnNumbers.size()) {
            throw new Exception("参数错误");
        }

        HashMap<Integer, Integer> idToNumber = new HashMap<>();
        for (int i = 0; i < orderDetailIds.size(); i++) {
            idToNumber.put(orderDetailIds.get(i), returnNumbers.get(i));
        }

        if (!Objects.equals(storehouseOrder.getUserId(), userId)) {
            throw new Exception("没有权限");
        }

        if (storehouseOrder.getStatus() != 5) {
            throw new Exception("不能重复归还");
        }

        storehouseOrder.setStatus(StorehouseOrder.STATUS_RETURNED);
        storehouseOrderRepository.save(storehouseOrder);

        List<StorehouseOrderDetail> details = storehouseOrderDetailRepository.findAllById(orderDetailIds);
        if (details.size() != orderDetailIds.size()) {
            throw new Exception("参数错误");
        }

        for (int i = 0; i < details.size(); i++) {
            float remain = (float) idToNumber.get(details.get(i).getId());
            StorehouseOrderDetail detail = details.get(i);
            detail.setReturnDetailNumber(remain);
            detail.setStatus(StorehouseOrder.STATUS_RETURNED);
            storehouseOrderDetailRepository.save(detail);

            HazardousChemicals hazardousChemicals = hazardousChemicalsRepository.getById(detail.getHjHazardousChemicalId());
            hazardousChemicals.setAmount(1f);
            hazardousChemicals.setResidue(remain);
            hazardousChemicalsRepository.save(hazardousChemicals);

            HazardousChemicalsTotal hazardousChemicalsTotal = hazardousChemicalsTotalRepository.findByNameAndType(
                    hazardousChemicals.getName(),
                    hazardousChemicals.getType()
            );

            if (hazardousChemicalsTotal != null) {
                hazardousChemicalsTotal.setTotalNumber(hazardousChemicalsTotal.getTotalNumber() + hazardousChemicals.getResidue());
                hazardousChemicalsTotalRepository.save(hazardousChemicalsTotal);
            } else {
                hazardousChemicalsTotal = new HazardousChemicalsTotal();
                hazardousChemicalsTotal.setTotalNumber(hazardousChemicals.getResidue());
                hazardousChemicalsTotal.setType(hazardousChemicals.getType());
                hazardousChemicalsTotal.setDangerClasses(hazardousChemicals.getDangerClasses());
                hazardousChemicalsTotal.setLabId(hazardousChemicals.getLabId());
                hazardousChemicalsTotal.setAmount(1);
                hazardousChemicalsTotal.setName(hazardousChemicals.getName());
                hazardousChemicalsTotal.setCabinetId(hazardousChemicals.getCabinetId());
                hazardousChemicalsTotal.setCountType(hazardousChemicals.getCountType());
                hazardousChemicalsTotalRepository.save(hazardousChemicalsTotal);
            }

            HazardousChemicalsChangeRecord hazardousChemicalsChangeRecord = new HazardousChemicalsChangeRecord();
            hazardousChemicalsChangeRecord.setCountType(hazardousChemicals.getCountType());
            hazardousChemicalsChangeRecord.setUserId(userId);
            hazardousChemicalsChangeRecord.setType(hazardousChemicals.getType());
            hazardousChemicalsChangeRecord.setName(hazardousChemicals.getName());
            hazardousChemicalsChangeRecord.setDetailNumber(hazardousChemicals.getResidue());

            hazardousChemicalsChangeRecord.setAmount(1f);//

            hazardousChemicalsChangeRecord.setHcId(hazardousChemicals.getId());
            hazardousChemicalsChangeRecord.setState(HazardousChemicalsChangeRecord.STATE_GIVE_BACK);

            hazardousChemicalsChangeRecord.setBatchNumber(hazardousChemicals.getBatchNumber());
            hazardousChemicalsChangeRecord.setNumber(hazardousChemicals.getNumber());//编号
            hazardousChemicalsChangeRecord.setIngredientData(hazardousChemicals.getIngredientData());
            hazardousChemicalsChangeRecord.setMatrix(hazardousChemicals.getMatrix());
            hazardousChemicalsChangeRecord.setExpirationDate(hazardousChemicals.getExpirationDate());
            hazardousChemicalsChangeRecord.setOrderId(orderId);

            hazardousChemicalsChangeRecord.setGhNumber(hazardousChemicals.getResidue());
            //1.根据用户id和化学试剂id 查询出该用户最近领取的该试剂的记录（按照时间排序最近一次优先）
            List<HazardousChemicalsChangeRecord> list = hazardousChemicalsChangeRecordRepository.getListByUserIdAndHcId(userId,hazardousChemicals.getId());
            //2.判断领取量大于归还量即可进行计算
            for (HazardousChemicalsChangeRecord hazardousChemicalsChangeRecord1 : list){
                if (hazardousChemicalsChangeRecord1.getLqNumber() >= hazardousChemicals.getResidue()){
                    //符合条件，领取量减去归还量作为使用量赋值给resources
                    hazardousChemicalsChangeRecord.setUsedNumber(hazardousChemicalsChangeRecord1.getLqNumber() - hazardousChemicals.getResidue());
                    //计算完毕，更新上面那条hazardousChemicalsChangeRecord的归还状态（is_return = 0）
                    hazardousChemicalsChangeRecordRepository.updateIsReturn(hazardousChemicalsChangeRecord1.getId());
                }
                break;
            }
            hazardousChemicalsChangeRecord.setIsReturn(2);//非领取操作
            hazardousChemicalsChangeRecordRepository.save(hazardousChemicalsChangeRecord);
        }

    }


    private Map<String, Object> getStringObjectMap(Pageable pageable, Specification<StorehouseOrder> specification) {
        Page<StorehouseOrder> page = storehouseOrderRepository.findAll(specification, pageable);
        Page<StorehouseOrderDto> dto = page.map(storehouseOrderMapper::toDto);
        List<StorehouseOrderDto> resultDto = dto.getContent();

        List<StorehouseOrderNumDto> storehouseOrderNumDtos = new ArrayList<>();
        for (StorehouseOrderDto storehouseOrderDto : resultDto) {
            ArrayList<Map> maps = new ArrayList<>();
            User user = userRepository.findById(Long.valueOf(storehouseOrderDto.getUserId())).orElseGet(User::new);
            storehouseOrderDto.setUserName(user.getUsername());
            List<StorehouseOrderNumDto> storehouseOrderNumDtoList = JSONObject.parseArray(storehouseOrderDto.getData(), StorehouseOrderNumDto.class);
            for (StorehouseOrderNumDto storehouseOrderNumDto : storehouseOrderNumDtoList) {
                storehouseOrderNumDtos.add(storehouseOrderNumDto);
//                storehouseOrderNumDto.setInventory(judgmentInventory(storehouseOrderNumDto));
                Lab lab = labRepository.findById(storehouseOrderNumDto.getLabId()).orElseGet(Lab::new);
                storehouseOrderNumDto.setLabName(lab.getName());
                Cabinet cabinet = cabinetRepository.findById(storehouseOrderNumDto.getCabinetId()).orElseGet(Cabinet::new);
                storehouseOrderNumDto.setCabinetName(cabinet.getName());
                if (storehouseOrderNumDto.getCountType() == 2) {
                    storehouseOrderNumDto.setNum(storehouseOrderNumDto.getAmount());
                }
                JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class);
                maps.add(JSON.parseObject(JSON.toJSONString(storehouseOrderNumDto), Map.class));
            }
            storehouseOrderDto.setStore(maps);
        }

        judgmentInventory(storehouseOrderNumDtos);

        return PageUtil.toPage(dto);
    }

    private static String generateOrderNo() {
        Date date = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateTime = df.format(date);
        String num = String.valueOf((int) (Math.random() * 1000000));
        return dateTime.concat(num);
    }

    //判断库存是否充足
    private int judgmentInventory(StorehouseOrderNumDto storehouseOrderNumDto) {
        HazardousChemicalsTotal total = hazardousChemicalsTotalRepository.findByNameAndType(
                storehouseOrderNumDto.getName(),
                storehouseOrderNumDto.getType()
        );
        if (total == null) {
            return 0;
        }

        float stock = hazardousChemicalsTotalRepository.sumTotalNumName(storehouseOrderNumDto.getName());

        if (stock >= storehouseOrderNumDto.getNum()) {
            return 1;
        }

        return 0;
    }

    //判断库存是否充足
    private void judgmentInventory(List<StorehouseOrderNumDto> storehouseOrderNumDtos) {
        List<HazardousChemicalsTotal> hazardousChemicalsTotals = hazardousChemicalsTotalRepository.findAll();
        Map<String, Float> nameToTotal = new HashMap<>();
        for (HazardousChemicalsTotal total :
                hazardousChemicalsTotals) {
            if (nameToTotal.containsKey(total.getName())) {
//                nameToTotal.put(nameToTotal.get(total.getName())+total.getTotalNumber());
                float newTotal = nameToTotal.get(total.getName()) + 2;
                nameToTotal.put(total.getName(), newTotal);
            } else {
                nameToTotal.put(total.getName(), total.getTotalNumber());
            }
        }

        for (StorehouseOrderNumDto storehouseOrderNumDto :
                storehouseOrderNumDtos) {
            if (!nameToTotal.containsKey(storehouseOrderNumDto.getName())) {
                storehouseOrderNumDto.setInventory(0);
            } else {
                if (nameToTotal.get(storehouseOrderNumDto.getName()) >= storehouseOrderNumDto.getNum()) {
                    storehouseOrderNumDto.setInventory(1);
                } else {
                    storehouseOrderNumDto.setInventory(0);
                }
            }
        }
    }
}
